Skip to content

fix: handle TsTypeAssertion that conflicts with JSX handling for tarball bundling#7049

Merged
pieh merged 7 commits into
mainfrom
fix/handle-TsTypeAssertion-when-rewriting-import-assertions
May 27, 2026
Merged

fix: handle TsTypeAssertion that conflicts with JSX handling for tarball bundling#7049
pieh merged 7 commits into
mainfrom
fix/handle-TsTypeAssertion-when-rewriting-import-assertions

Conversation

@pieh

@pieh pieh commented May 8, 2026

Copy link
Copy Markdown
Contributor

🎉 Thanks for submitting a pull request! 🎉

Summary

Primary motivation here is not NOT fail bundling when .wasm import happens + handle currently unsupported <Type> variable syntax for casting.

For the .wasm handling important note is that we are NOT actually using the wasm imported module in runtime as of now and this is only to unblock bundling. We should be falling back to pre deno@2.1 handling (so either fetching or instantiating wasm module from inline bytes).

The fact that deno@2.6.0 changed the way vendored .wasm modules are being handled is a bit problematic. It does mean that if we will want to actually support them (instead of just pre deno@2.1 way) - we will need to keep the difference in mind - we will either need to ensure that runtime version matches deno version used for bundling (at least the pre/post 2.6.0 ranges, it probably won't have to match exactly) OR runtime will need to somehow provide compatibility layer to adjust bundle so mismatched wasm handling would be addressed


For us to review and ship your PR efficiently, please perform the following steps:

  • Open a bug/issue before writing your code 🧑‍💻. This ensures
    we can discuss the changes and get feedback from everyone that should be involved. If you`re fixing a typo or
    something that`s on fire 🔥 (e.g. incident related), you can skip this step.
  • Read the contribution guidelines 📖. This ensures
    your code follows our style guide and passes our tests.
  • Update or add tests (if any source code was changed or added) 🧪
  • Update or add documentation (if features were changed or added) 📝
  • Make sure the status checks below are successful ✅

A picture of a cute animal (not mandatory, but encouraged)

@coderabbitai

coderabbitai Bot commented May 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 137d26ed-fb65-4bbd-ba65-c69c9443bb94

📥 Commits

Reviewing files that changed from the base of the PR and between 052591b and 0645a65.

📒 Files selected for processing (7)
  • .github/workflows/workflow.yml
  • packages/edge-bundler/node/bundler.test.ts
  • packages/edge-bundler/node/formats/tarball.ts
  • packages/edge-bundler/node/utils/import_attributes.test.ts
  • packages/edge-bundler/node/utils/import_attributes.ts
  • packages/edge-bundler/test/fixtures/imports_deno_dom_wasm/netlify/edge-functions/func1.ts
  • packages/edge-bundler/test/util.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/edge-bundler/test/fixtures/imports_deno_dom_wasm/netlify/edge-functions/func1.ts

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added support for bundling modules that import WebAssembly binaries to edge functions.
  • Bug Fixes

    • Improved handling of TypeScript syntax that could be mis-parsed during import assertion rewriting.
    • Enhanced WebAssembly file detection by validating magic bytes instead of relying solely on file extensions.
  • Chores

    • Updated maximum supported Deno version to v2.8.0.

Walkthrough

This PR makes multiple edge-bundler changes: replace direct acorn.parse calls with a new parseAST that tries JSX parsing and retries without JSX on SyntaxError; add a Vitest for the TypeScript type-assertion vs JSX parsing edge case; add WASM magic-byte detection and a shouldRewrite check in tarball import-assertion rewriting with safer error handling; add a deno_dom WASM fixture and tarball inspect template updates; adjust bundler tests and bump the CI Deno matrix to v2.8.0.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main fix: handling TsTypeAssertion conflicts with JSX parsing during tarball bundling.
Description check ✅ Passed The description explains the motivation (preventing bundling failures for .wasm imports and handling TsTypeAssertion syntax), provides context about deno@2.6.0 changes, and acknowledges the pre-deno@2.1 fallback approach.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/handle-TsTypeAssertion-when-rewriting-import-assertions

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

// We want to make sure we can handle this case and still rewrite the import assertions correctly.
const source = `
import data3 from './data.json' assert { type: 'json' };
const params = <Params> inputs;

@pieh pieh May 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is valid and documented syntax - https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#type-assertions - it just conflicts in JSX mode because angled brackets become ambiguous so parsers intentionally disable handling of this syntax for type casting in JSX mode

@pieh pieh marked this pull request as ready for review May 8, 2026 11:39
@pieh pieh requested a review from a team as a code owner May 8, 2026 11:39
Comment on lines +21 to +32
const parseAST = (source: string): Program => {
try {
return acornJSX.parse(source, parseOptions)
} catch (error) {
// for non-jsx typescript casting to type via "<type> value" (normally done with "value as type") will throw an "Unexpected token" error in acorn-jsx,
// but is valid syntax in TypeScript. In this case, we can retry parsing with the non-jsx parser.
if (error instanceof SyntaxError) {
return acornNoJSX.parse(source, parseOptions)
}
throw error
}
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential alternative I considered is picking parser based on extension (with .ts specifically using NoJSX mode), but fallback felt like more sure thing that is potentially not susceptible to wild and unexpected configurations

@pieh pieh marked this pull request as draft May 13, 2026 07:23
@pieh pieh force-pushed the fix/handle-TsTypeAssertion-when-rewriting-import-assertions branch 2 times, most recently from 75fb8b8 to 0360098 Compare May 25, 2026 10:26
@pieh pieh force-pushed the fix/handle-TsTypeAssertion-when-rewriting-import-assertions branch from 0360098 to 9d8b483 Compare May 25, 2026 10:51
Comment on lines -111 to +116
.replace(/file:\/\/\/(.*?\/)(build\/packages\/edge-bundler\/deno\/vendor\/deno\.land\/x\/eszip.*)/, 'file://$2')
// eslint-disable-next-line no-control-regex
.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, ''),
.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, '')
.replace(
/file:\/\/\/(.*?\/)(build\/packages\/edge-bundler\/deno\/vendor\/deno\.land\/x\/eszip.*)/,
'file://$2',
),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

swap places so formatting removal is before path normalization. Seems like some newer deno version messed with formatting so previous order was not working anymore and then path normalization was not being applied

Comment on lines +1357 to +1364
// The vendored deno_dom WASM payload must be present in the tarball.
// Deno <2.6 vendors `.wasm` imports under a `.d.mts` extension (with a
// content-hash suffix); 2.6+ keeps the original `.wasm` extension.
const denoDomVendorPrefix = './vendor/deno.land/x/deno_dom@v0.1.56/build/deno-wasm/'
const expectedWasmEntry = lt(denoVersion, '2.6.0')
? `${denoDomVendorPrefix}#deno-wasm_bg.wasm_d2792.d.mts`
: `${denoDomVendorPrefix}deno-wasm_bg.wasm`
expect(entries).toContain(expectedWasmEntry)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love check like this - bit I added it here to somewhat show that wasm handling is deno-version dependant and give some more context around added byte sniffing for .ts extension that should be text/code and not a wasm binary

@pieh pieh marked this pull request as ready for review May 26, 2026 06:38
Comment on lines -76 to +79
const entrypoint = path.resolve(manifest.functions[functionName]);
const func = await import(pathToFileURL(entrypoint))
// Import via a relative specifier so Deno resolves the module URL itself,
// keeping its encoding consistent with the import map base (both derived from
// cwd). Pre-building an absolute file:// URL on the Node side encodes paths
// differently from Deno (e.g. '~' in Windows 8.3 short names), which breaks
// import map prefix matching on Deno 2.8+.
const func = await import("./" + manifest.functions[functionName]);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This did not work on Windows Github Actions runner with fresh deno - overall it looks like windows quirk. It worked fine on non-windows, so this doesn't seem like something to be concerned about actual EF runtime

deno-version: ['v2.4.2']
# Maximum supported deno version from the `DENO_VERSION_RANGE` constant in `node/bridge.ts`.
# If there is no upper band - this should be set to whatever is the latest deno version at the time of updating this workflow.
deno-version: ['v2.8.0']

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional side effect is that github commit checks have different names, so "required checks" will need to be updated before merging.

Fact that currently set ones did not run is result of this change.

We do use min deno version in variant below, so that we have min and max deno version cases covered

@pieh pieh merged commit 3d2a644 into main May 27, 2026
53 of 56 checks passed
@pieh pieh deleted the fix/handle-TsTypeAssertion-when-rewriting-import-assertions branch May 27, 2026 10:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants